//
// Created by hkkzzxz on 24-8-31.
//

#include "HttpConnection.h"
#include "HttpRouter.h"

void HttpConnection::start() {
    // 异步接收完整的HTP请求消息
    readRequest();
    // 检测是否超时
    checkDeadline();
}

void HttpConnection::readRequest() {
    auto self = shared_from_this();
    http::async_read(tcpSocket, httpBuffer, httpRequest,
                     [self](beast::error_code ec, std::size_t bytes_transferred) {
                         boost::ignore_unused(bytes_transferred);
                         if (!ec)
                             self->processRequest();
                     });
}

void HttpConnection::processRequest() {
    // 处理路由
    HttpRouter *httpRouter = HttpRouter::getInstance();
    // 设置相应与请求版本相同
    httpResponse.version(httpRequest.version());
    httpResponse.keep_alive(false);

    // 设置CORS跨域许可
    httpResponse.set(http::field::access_control_allow_origin, "*");
    httpResponse.set(http::field::access_control_allow_methods, "GET,POST,OPTIONS");
    httpResponse.set(http::field::access_control_allow_headers, "Content-Type,Authorization");


    // 根据请求的方法（GET或POST）来决定如何处理
    switch (httpRequest.method()) {
        case http::verb::get:
            // 设置响应的服务器头为"YunShiServer"
            httpResponse.set(http::field::server, "YunShiServer");
            // 调用函数来创建GET请求的响应
            httpRouter->GETSelect(httpRequest, httpResponse);
            break;

        case http::verb::post:
            // 设置响应的服务器头为"YunShiServer"
            httpResponse.set(http::field::server, "YunShiServer");
            // 调用函数来创建POST请求的响应
            httpRouter->POSTSelect(httpRequest, httpResponse);
            break;

        case http::verb::options:
            // 对于预检请求，设置200状态码
            httpResponse.result(http::status::ok);
            httpResponse.set(http::field::content_length, "0");
            break;

        default:
            // 如果请求方法不是GET或POST，返回一个错误响应
            httpResponse.result(http::status::bad_request);
            // 设置响应的内容类型为纯文本
            httpResponse.set(http::field::content_type, "text/plain");
            // 使用Beast的输出流来写入错误信息到响应体
            beast::ostream(httpResponse.body())
                    << "Invalid request-method '"
                    << std::string(httpRequest.method_string())
                    << "'";
            break;
    }
    // 调用函数来写回响应
    writeResponse();
}

void HttpConnection::writeResponse() {
    auto self = shared_from_this();

    httpResponse.content_length(httpResponse.body().size());

    http::async_write(tcpSocket, httpResponse,
                      [self](beast::error_code ec, std::size_t) {
                          if (!ec) {
                              self->tcpSocket.shutdown(tcp::socket::shutdown_send, ec);
                              self->httpDeadline.cancel();
                          } else if (ec != boost::asio::error::eof) {
                              // 错误处理：关闭连接
                              self->tcpSocket.lowest_layer().close(ec);
                          }
                      });
}

void HttpConnection::checkDeadline() {
    auto self = shared_from_this();
    httpDeadline.async_wait([self](beast::error_code ec) {
                                if (!ec) {
                                    // 关闭套接字以取消任何未完成的操作。
                                    self->tcpSocket.lowest_layer().close(ec);
                                }
                            }
    );
}
